/**
 * <AiRmob-Framework; A simple augmented reality framework for android >
    Copyright (C) <2012>  <AiRmob Team>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package rendercomponents;

import android.opengl.Matrix;

public class Light extends Object {
	private float lightDiffuse[] = { 1, 1, 1, 1 };
	private float lightSpecular[] = { 1, 1, 1, 1 };

	private float position[] = { 100, 50, 150 };
	private float direction[] = { 0, -50, -100 };
	private float up[] = { 0, -1, 0 };
	// exponent range: 1 to infinite
	// bigger exponent equals smoother cone edge
	private float exponent = 1;
	// angle range: 0 to 180 degrees
	// cone size depends on angle size
	private float angle = 20;

	// Is calculated whenever a light is constructed or one of position,
	// direction or up is changed
	private float view[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	// Is calculated in the renderer
	private float perspective[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0 };

	// Is calculated in the scenemanager
	private float MVMatrix[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	/**
	 * 
	 * @return the view-matrix of this light.
	 */
	public float[] getView() {
		return view;
	}

	/**
	 * Sets the view-matrix of this light. Expects a float[16] as input.
	 * 
	 * @param view
	 */
	public void setView(float[] view) {
		this.view = view;
	}


	/**
	 * 
	 * @return the diffuse-color of this light as float[4].
	 */
	public float[] getLightDiffuse() {
		return lightDiffuse;
	}

	/**
	 * Sets the diffuse-color of this light. Expects a float[4]
	 * (red/blue/green/alpha) as input.
	 * 
	 * @param lightDiffuse
	 */
	public void setLightDiffuse(float[] lightDiffuse) {
		this.lightDiffuse = lightDiffuse;
	}

	/**
	 * 
	 * @return the diffuse-color of this light as float[4].
	 */
	public float[] getLightSpecular() {
		return lightSpecular;
	}

	/**
	 * Sets the specular-color of this light. Expects a float[4]
	 * (red/blue/green/alpha) as input.
	 * 
	 * @param lightSpecular
	 */
	public void setLightSpecular(float[] lightSpecular) {
		this.lightSpecular = lightSpecular;
	}

	/**
	 * 
	 * @return the direction of this light as float[3].
	 */
	public float[] getDirection() {
		return direction;
	}

	/**
	 * 
	 * Sets the direction of this light. Expects a float[3] (x/y/z) as input.
	 * 
	 * @param direction
	 */
	public void setDirection(float[] direction) {
		this.direction = direction;
		this.calculateView();
	}

	/**
	 * Constructs a light with standard-values.
	 */
	public Light() {
		this.type = 5;
		this.calculateView();
	}

	/**
	 * 
	 * Constructs a light with given values.
	 * 
	 * @param position
	 * @param direction
	 * @param up
	 * @param exponent
	 */
	public Light(float[] position, float[] direction, float[] up, float exponent) {
		this.type = 5;
		this.position = position;
		this.direction = direction;
		this.exponent = exponent;
		this.up = up;
		this.calculateView();
	}

	private void calculateView() {
		Matrix.setLookAtM(this.view, 0, this.getPosition()[0],
				this.getPosition()[1], this.getPosition()[2],
				this.getDirection()[0], this.getDirection()[1],
				this.getDirection()[2], this.getUp()[0], this.getUp()[1],
				this.getUp()[2]);
	}

	/**
	 * 
	 * @return the position of this light as float[3].
	 */
	public float[] getPosition() {
		return position;
	}

	/**
	 * Sets the position of this light. Expects a float[3] (x/y/z) as input.
	 * 
	 * @param position
	 */
	public void setPosition(float[] position) {
		this.position = position;
		this.calculateView();
	}

	/**
	 * 
	 * @return the exponent of this light as float.
	 */
	public float getExponent() {
		return exponent;
	}

	/**
	 * Sets the exponent of this light.
	 * 
	 * @param exponent
	 */
	public void setExponent(float exponent) {
		this.exponent = exponent;
	}

	/**
	 * 
	 * @return the angle of this light as float.
	 */
	public float getAngle() {
		return angle;
	}

	/**
	 * Sets the angle of this light.
	 * 
	 * @param angle
	 */
	public void setAngle(float angle) {
		this.angle = angle;
	}

	/**
	 * 
	 * @return the perspective of this light as float[16].
	 */
	public float[] getPerspective() {
		return perspective;
	}

	/**
	 * Manually sets the perspective-matrix of this light. Expects a float[16]
	 * as input.
	 * 
	 * @param perspective
	 */
	public void setPerspective(float[] perspective) {
		this.perspective = perspective;
	}

	/**
	 * 
	 * @return the up-vector of this light as float[3].
	 */
	public float[] getUp() {
		return up;
	}

	/**
	 * Sets the up-vector. Expects a float[3] as input.
	 * 
	 * @param up
	 */
	public void setUp(float[] up) {
		this.up = up;
		this.calculateView();
	}

	/**
	 * The model-view-matrix of a light will calculated in the scene-manager
	 * when the scenegraph is build.
	 * 
	 * @return the model-view-matrix of this light as float[16].
	 */
	public float[] getMVMatrix() {
		return MVMatrix;
	}

	/**
	 * Manually set the model-view-matrix of this light. Will be overwritten as
	 * soon as the scenegraph is rebuild. Expects a float[16] as input.
	 * 
	 * @param mVMatrix
	 */
	public void setMVMatrix(float[] mVMatrix) {
		MVMatrix = mVMatrix;
	}

}